package org.NooLab.itexx.app.processes;

import java.util.ArrayList;
import java.util.Observable;
import java.util.Observer;

import org.NooLab.itexx.ITexxWindowCommons;
import org.NooLab.itexx.app.config.ITexxAppPropertiesIntf;
import org.NooLab.itexx.app.processes.LinguisticsPort.LingResultsImportGateway;
import org.NooLab.itexx.app.processes.comm.CommBoxArrivalIntf;
import org.NooLab.itexx.retrieval.RequestDispatcher;
import org.NooLab.nlp.structures.NLPresultSet;

import org.NooLab.structures.nlp.NlpProcessInfo;
import org.NooLab.utilities.logging.PrintLog;
import org.NooLab.utilities.objects.StringedObjects;
import org.NooLab.utilities.strings.ArrUtilities;




/**
 * 
 * The purpose of this object is to collect the results that are delivered by the 
 * linguistics sub-process.</br>
 * it gets constructed in AppCommons;</br></br> 
 * 
 * it gets updated directly by the tcpReceiver, which is served by the 
 * linguistic subprocess (NooLabNLP) !
 * This is defined in ProcessAdmin::startLinguisticsProcess()
 * 
 * The LinguisticsPort itself is observed by the "RequestGenerator", which before
 * also issued the tcp message to the linguistic sub-process
 * 
 * 
 *
 */
public class LinguisticsPort extends Observable implements Observer, CommBoxArrivalIntf {

	ITexxWindowCommons appCommons;
	RequestDispatcher requestDispatcher;
	ITexxAppPropertiesIntf lpProperties;
	
	
	/** items will be removed from there on delivery */
	ArrayList<String> registeredResultsCollection = new ArrayList<String>();
	ArrayList<NLPresultSet> consolidatedResults = new ArrayList<NLPresultSet>();
	
	
	
	PrintLog out; 
	StringedObjects so = new StringedObjects ();
	 
		
	// ========================================================================
	public LinguisticsPort( ITexxWindowCommons commons){
		init(commons);
	}

	public LinguisticsPort( ITexxWindowCommons commons, 
							RequestDispatcher rqDispatcher) {
		// 
		
		requestDispatcher = rqDispatcher;
		init(commons);
		
	}
	// ========================================================================
	private void init(ITexxWindowCommons commons) {

		appCommons = commons;
		
		lpProperties = appCommons.getAppProperties();
		out = appCommons.out ;
		
		if (appCommons.getRequestDispatcher()!=null){
			this.addObserver(appCommons.getRequestDispatcher());
		}
	}

	
	// later: the result set should know whether it is the last of a series, else it needs the gui
	@Override
	public void update(Observable sender, Object dataobj) {
		
		out.print(2,"LinguisticsPort received a message from      : "+sender.toString());
		out.print(3,"LinguisticsPort received a message of format : "+dataobj.toString());
		out.delay(10);
		
		// just an internal class for fast branching
		// therein, the data will be processed 
		LingResultsImportGateway lig = new LingResultsImportGateway(dataobj);
		lig.importText();
													    
	}

	public void consolidateWordSets( NLPresultSet resultSet ){
		
		(new LingResultsImportGateway(resultSet)).importText();
	}
	
	class LingResultsImportGateway{

		
		Object dataobj, obj;
		
		public LingResultsImportGateway(Object dataobj) {
			this.dataobj = dataobj;
			
			if (lpProperties==null){
				lpProperties = appCommons.getAppProperties() ;
			}
		}
		
		public void importText(){
			

			NLPresultSet resultSet = null;
			String str="";
			
			out.setPrefix("[iTexx-Gui]");
			
			String cn = dataobj.getClass().getSimpleName().toLowerCase() ;
			if (cn.contains("string[]")){
				str = ((String[])dataobj)[1];
			}
			if ((str.length()>0) && (str.startsWith("rO0"))){
				obj = so.decode(str) ; 
				if (obj==null){
					String errStr = so.lastError ;
					out.printErr(1, "Format recognized as encoded object, but decoding yielded null (length was "+str.length()+" chars)");
					out.printErr(1, "last recorded error was: "+errStr);  
					cn = "null";
					if (obj==null){
						return;
					}
				}else{
					cn = obj.getClass().getSimpleName().toLowerCase() ;
				}
				if (obj instanceof NLPresultSet){
					resultSet = (NLPresultSet)obj; 
				}
			}
			
			if ((resultSet==null) || (obj instanceof NLPresultSet)==false){
				String df="?";
				if ((obj==null) || (obj instanceof NlpProcessInfo )==false){
					out.printErr(1, "Unknown format ");
				}
				if (dataobj!=null){
					checkForProcessMessage(obj);
				}
				if (resultSet!=null){
				
					out.printErr(1, "Unknown data format ("+df+" "+resultSet.toString()+")");
				}
				return;
			}

			
			
			str = resultSet.getallPoSasStr() ;     	out.print(2,"\n\nin-process result:\n   annotated    : "+ str) ;
			str = resultSet.getCoreSentence() ;    	out.print(3,"   core phrase  : " + str) ;
			
			str = ArrUtilities.arr2Text(resultSet.getCollectedVerbPhrases(), "; ");
												   	out.print(3,"   verb phrases : " + str) ;
			str = resultSet.getMainPhrase();       	out.print(3,"   main phrase  : " + str) ;
							
		
			str = ArrUtilities.arr2Text( resultSet.getWordsetLabels(), "\n                  ") ;
												    out.print(2,"   word sets    : " + str) ;
												    out.print(2,"   ================================ \n") ;

			// collecting results ?		
	        str="";
	    
	        
	        deliver(resultSet);
	        /*
	        
	        if ((lpProperties.consolidateLingWordSets()) && 
	        	(resultSet.isLastResultSet()==false) && (resultSet.getGuid().length()>0)){
	        
	        	String rguid = resultSet.getGuid();
	        	
	        	if (registeredResultsCollection.indexOf(rguid)<0){
	        		openResultsCollection(rguid);
	        	}else{
	        		integrateCurrentSet(rguid,resultSet) ;
	        	}
	        	
	        }else{

	        	deliver(resultSet);
	        }
			*/
		}

		private void checkForProcessMessage(Object dataobj) {
			// 
			NlpProcessInfo npi;
			
			if (dataobj instanceof NlpProcessInfo ){
				npi = (NlpProcessInfo)dataobj;
				if (npi!=null){
					appCommons.getProcessAdmin().checkProcessInfo(npi);
					// out.printErr(3, " ----------------------------- " +npi.getText());
				}
			}
		}

		private void deliver(NLPresultSet resultSet) {

 
        	// registeredResultsCollection 
        	// consolidatedResults 

			// this will inform the Observer update() of RequestDispatcher
			// items will be removed from there on delivery
			setChanged();
            notifyObservers(resultSet);
		}
		
	}

	private void integrateCurrentSet(String rguid, NLPresultSet resultSet) {

		NLPresultSet cresult = null;
		
		for (int i=0;i<consolidatedResults.size();i++){
			NLPresultSet cr = consolidatedResults.get(i);
			if (cr.getGuid().contentEquals(rguid)){
				cresult = cr;
				break;
			}
		}
		if (cresult != null){
			integrateResultSet(cresult,resultSet) ;
		}
	}

	
	private void integrateResultSet(NLPresultSet cresult, NLPresultSet resultSet) {

	
	}

	private void openResultsCollection(String guid) {
		
		registeredResultsCollection.add(guid);
		NLPresultSet resultSet = new NLPresultSet ();
		
		consolidatedResults.add(resultSet) ;
		
	}

}
